﻿using Newtonsoft.Json;
using TaskManagerLib.Symbol;

namespace TaskManagerLib.MinimumWork;

public abstract class MiniWork<T>: IMiniWork<T>
{
    public double Progress { get; set; }
    [JsonIgnore]
    public ProgressDelegate? Notification { get; set; }
    public WorkStatus? Status { get; set; }
    public abstract bool IsFinished();

    public Type? ResultType { get; }
    public T? Result { get; set; }
    public string? ResultDescription { get; set; }
    [JsonIgnore]
    public CancellationTokenSource? CancellationTokenSource { get; set; }
    [JsonIgnore]
    public Task<int>? InnerTask { get; set; }

    public virtual Task<bool> Checkout()
    {
        return Task.FromResult(CanPausedAndRunWithoutInformationLost());
    }

    public virtual Task BuildContinuesTask()
    {
        if (UseRecoverAction())
        {
            var task = new Task<int>(() =>
            {
                Task.Run(async () =>
                {
                    await RecoverAction();
                }).GetAwaiter().GetResult();
                return IMiniWork.Success;
            });
            InnerTask = task;
        }
        else
        {
            var task = new Task<int>(() =>
            {
                Task.Run(async () =>
                {
                    await Action();
                }).GetAwaiter().GetResult();
                return IMiniWork.Success;
            });
            InnerTask = task;
        }

        return Task.CompletedTask;
    }

    public abstract bool Resume(CancellationTokenSource cancellationTokenSource);

    public virtual bool CanBePaused()
    {
        return true;
    }

    public virtual bool CanPausedAndRunWithoutInformationLost()
    {
        return false;
    }

    public virtual bool CanReRun()
    {
        return true;
    }

    public virtual bool UseRecoverAction()
    {
        return true;
    }

    public abstract Task Action();

    public virtual Task RecoverAction()
    {
        return Task.CompletedTask;
    }

    public void Start()
    {
        try
        {
            if (InnerTask == null) return;
            Task.Run(async () =>
            {
                InnerTask.Start();
                Status = WorkStatus.Running;
                await InnerTask;
            });


        }
        catch (Exception)
        {
            Status = WorkStatus.Except;
        }
    }
    public async Task StartAndBlockAsync()
    {
        try
        {
            if (InnerTask == null) return;
            InnerTask.Start();
            Status = WorkStatus.Running;
            await InnerTask;
        }
        catch (Exception)
        {
            Status = WorkStatus.Except;
        }
    }
    // 构建要执行的任务
    public void Build()
    {
        var task = new Task<int>(() =>
        {
            Task.Run(async () =>
            {
                await Action();
            }).GetAwaiter().GetResult();
            return IMiniWork.Success;
        });
        InnerTask = task;
    }
}